namespace Aphalina.Compression
{
    using System;
    using System.IO;
    using System.Runtime.CompilerServices;

    public class BitReader
    {
        private int bitLength;
        private static uint[] bitMask = new uint[0x20];
        private int currentBits;

        static BitReader()
        {
            bitMask[1] = 1;
            for (int i = 2; i < 0x20; i++)
            {
                bitMask[i] = (bitMask[i - 1] << 1) | 1;
            }
        }

        public BitReader(Stream stream)
        {
            this.BaseStream = stream;
        }

        public void AlignToByte()
        {
            this.bitLength = 0;
        }

        public void CopyTo(Stream memory, int length)
        {
            byte[] buffer = new byte[length];
            int count = this.BaseStream.Read(buffer, 0, length);
            memory.Write(buffer, 0, count);
        }

        public int ReadBits(int length)
        {
            long num = 0;
            int num2 = 0;
            while (length > 0)
            {
                if (this.bitLength == 0)
                {
                    this.currentBits = this.BaseStream.ReadByte();
                    if (this.currentBits == -1)
                    {
                        throw new Exception("NeedData");
                    }
                    this.bitLength = 8;
                }
                int index = length;
                if (index > this.bitLength)
                {
                    index = this.bitLength;
                }
                num |= (bitMask[index] & this.currentBits) << num2;
                this.currentBits = this.currentBits >> index;
                num2 += index;
                this.bitLength -= index;
                length -= index;
            }
            return (int) num;
        }

        public Stream BaseStream { get; private set; }
    }
}

